package org.domon.manager.base.mybatis;

import java.lang.reflect.Field;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.domon.manager.base.mybatis.annotation.Column;
import org.domon.manager.base.mybatis.annotation.ID;
import org.domon.manager.base.mybatis.annotation.Table;
import org.domon.manager.base.mybatis.sql.TableStructure;

/**
 * MyBatis用POJO基类
 * 
 * @author Domon.Xie
 * 
 */
public class MyBatisPojo {

	/**
	 * 等于
	 */
	public final static String EQ = "=";
	/**
	 * 不等于
	 */
	public final static String NEQ = "!=";
	/**
	 * 大于
	 */
	public final static String GT = ">";
	/**
	 * 大于等于
	 */
	public final static String GTE = ">=";
	/**
	 * 小于
	 */
	public final static String LT = "<";
	/**
	 * 小于等于
	 */
	public final static String LTE = "<=";

	/**
	 * 用于存放POJO对应的表信息
	 */
	private TableStructure table = new TableStructure();

	/**
	 * 构建update sql时使用：所需要修改的字段集
	 */
	private String[] updateField = {};

	/**
	 * 构建select sql时使用：所需要查询的字段集，如为空，则默认查全部字段
	 */
	private String[] selectResultField = {};

	/**
	 * 构建delete/update/select sql时使用：所需要过滤的字段集
	 */
	private String[] whereField = {};
	/**
	 * whereField的单参数运算符:[=][!=][>][>=][<][<=]
	 */
	private String[] whereFieldChar = {};

	/**
	 * 构建select sql时使用：所需要排序的字段集
	 */
	private String[] orderField = {};

	public MyBatisPojo() {
		setTableName();
		setColumns(this.getClass());
	}

	public TableStructure getTable() {
		return table;
	}

	public String[] getUpdateField() {
		return updateField;
	}

	/**
	 * 清空update字段
	 * 
	 * @param updateField
	 */
	public void setUpdateFieldEmpty() {
		this.updateField = ArrayUtils.EMPTY_STRING_ARRAY;
	}

	/**
	 * 追加update字段
	 * 
	 * @param updateField
	 */
	public void setUpdateField(String... updateField) {
		this.updateField = ArrayUtils.addAll(this.updateField, updateField);
	}

	public String[] getSelectResultField() {
		return selectResultField;
	}

	/**
	 * 清空查询结果集字段
	 * 
	 * @param selectResultField
	 */
	public void setSelectResultFieldEmpty() {
		this.selectResultField = ArrayUtils.EMPTY_STRING_ARRAY;
	}

	/**
	 * 追加查询结果集字段
	 * 
	 * @param selectResultField
	 */
	public void setSelectResultField(String... selectResultField) {
		this.selectResultField = ArrayUtils.addAll(this.selectResultField, selectResultField);
	}

	public String[] getWhereField() {
		return whereField;
	}

	public String[] getWhereFieldChar() {
		return whereFieldChar;
	}

	/**
	 * 清空where条件字段
	 * 
	 * @param whereField
	 */
	public void setWhereFieldEmpty() {
		this.whereField = ArrayUtils.EMPTY_STRING_ARRAY;
		this.whereFieldChar = ArrayUtils.EMPTY_STRING_ARRAY;
	}

	/**
	 * 追加where条件字段，默认为相等
	 * 
	 * @param whereField
	 */
	public void setWhereField(String... whereField) {
		for (int i = 0; i < whereField.length; i++) {
			this.setWhereFieldWithChar(EQ, whereField[i]);
		}
	}

	/**
	 * 追加where条件字段
	 * 
	 * @param whereFieldChar
	 *            运算符
	 * @param whereField
	 *            字段
	 */
	public void setWhereFieldWithChar(String whereFieldChar, String whereField) {
		this.whereField = ArrayUtils.addAll(this.whereField, whereField);
		this.whereFieldChar = ArrayUtils.addAll(this.whereFieldChar, whereFieldChar);
	}

	public String[] getOrderField() {
		return orderField;
	}

	/**
	 * 清空排序字段
	 * 
	 * @param orderField
	 */
	public void setOrderFieldEmpty() {
		this.orderField = ArrayUtils.EMPTY_STRING_ARRAY;
	}

	/**
	 * 追加排序字段
	 * 
	 * @param orderField
	 */
	public void setOrderField(String... orderField) {
		this.orderField = ArrayUtils.addAll(this.orderField, orderField);
	}

	/**
	 * 获取POJO对应的表名 需要POJO中的属性定义@Table(name)
	 * 
	 * @return
	 */
	private void setTableName() {
		Table table = this.getClass().getAnnotation(Table.class);
		if (table != null) {
			this.table.setTableName(table.value());
		} else {
			throw new RuntimeException("undefine POJO @Table, need Tablename(@Table(name))");
		}
	}

	/**
	 * 获取POJO中的主键字段名/一般字段名，需要定义@Id / @Column
	 * 
	 * @return
	 */
	private void setColumns(Class<?> clz) {
		// 父类字段
		if (clz.getSuperclass().getDeclaredFields().length != 0) {
			setColumns(clz.getSuperclass());
		}

		for (Field field : clz.getDeclaredFields()) {
			// 主键，子类会覆盖掉父类的ID注解标记
			if (field.isAnnotationPresent(ID.class)) {
				this.table.setId(field.getName());
			}

			if (field.isAnnotationPresent(Column.class)) {
				String column = StringUtils.isBlank(field.getAnnotation(Column.class).value()) ? field.getName() : field.getAnnotation(
						Column.class).value();
				this.table.getColumns().put(field.getName(), column);
			}
		}
	}
}